package com.javatom.notes.authority.config;

import com.javatom.notes.authority.service.Outh2UserDetailsService;
import com.javatom.notes.authority.sms.SmsCodeAuthenticationProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.annotation.Resource;

@Configuration
@EnableWebSecurity
public class OAth2WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private LogoutSuccessHandler logoutSuccessHandler;

    /**
     *  里面只有一个方法叫做loadUserByUserName。
     *  这个方法的作用就是通过用户名来获取详细的用户信息。
     *  一般情况下这个接口的实现类需要我们自己去写。在实现类里面通过去查询数据库拿着这个用户名。
     *  查出相关的用户信息来。
     *  如果查不到用户，就抛出UsernameNotFundException
     */
    @Autowired
    private Outh2UserDetailsService outh2UserDetailsService;


    @Resource
    private AuthenticationEntryPoint authenticationEntryPoint;
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(outh2UserDetailsService)
                .passwordEncoder(passwordEncoder());
    }



    @Override
    protected void configure(HttpSecurity http) throws Exception {
        SmsCodeAuthenticationProvider smsCodeAuthenticationProvider = new SmsCodeAuthenticationProvider();
        smsCodeAuthenticationProvider.setOuth2UserDetailsService(outh2UserDetailsService);
        http.authenticationProvider(smsCodeAuthenticationProvider).
                authorizeRequests().
                anyRequest().
                authenticated().
                and().
                exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
                .and().
                httpBasic().
                and().
                logout().logoutSuccessHandler(logoutSuccessHandler);
    }
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
